package com.smartleanx.module.hrm.service.esign.auth.impl;

import cn.hutool.core.util.StrUtil;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.smartleanx.framework.security.core.util.SecurityFrameworkUtils;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.esign.ElecCorp;
import com.smartleanx.module.hrm.dal.dataobject.esign.ElecCorpDept;
import com.smartleanx.module.hrm.dal.dataobject.esign.EsignOrgMember;
import com.smartleanx.module.hrm.dal.dataobject.esign.EsignPsnInfo;
import com.smartleanx.module.hrm.dal.mysql.employee.EmployeeMapper;
import com.smartleanx.module.hrm.dal.mysql.esign.*;
import com.smartleanx.module.hrm.service.esign.auth.CommonService;
import com.smartleanx.module.hrm.service.esign.auth.IElecCorpService;
import com.smartleanx.module.hrm.service.esign.bo.ElecCorpCreateBo;
import com.smartleanx.module.hrm.service.esign.bo.ElecCorpSelectBo;
import com.smartleanx.module.hrm.service.esign.bo.ElecCorpUpdateBo;
import com.smartleanx.module.hrm.service.esign.bo.OrgIdentifyBo;
import com.smartleanx.module.hrm.service.esign.temp.po.HrmEContractTask;
import com.smartleanx.module.hrm.service.esign.temp.vo.Auth.EsignProperties;
import com.smartleanx.module.hrm.service.esign.temp.vo.Auth.OrgAuthResp;
import com.smartleanx.module.hrm.service.esign.vo.ElecCorpDetailVo;
import com.smartleanx.module.hrm.service.esign.vo.ElecCorpPermissionVo;
import com.smartleanx.module.hrm.service.esign.vo.ElecCorpSelectVo;
import com.smartleanx.module.hrm.service.esign.vo.OrgIdentifyVo;
import com.smartleanx.module.hrm.service.examine.util.exception.EsignException;
import com.smartleanx.module.hrm.service.examine.util.exception.ResultException;
import com.smartleanx.module.hrm.util.DateUtil;
import com.smartleanx.module.hrm.util.esign.constant.OrgAuthScope;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.smartleanx.module.hrm.util.SaasBeanUtils.copyBeanProps;
import static com.smartleanx.module.hrm.util.esign.DesensitizationUtils.desensitizeIdNumber;


/**
 * @author yanglihao
 */
@Slf4j
@Service
@AllArgsConstructor
public class ElecCorpServiceImpl implements IElecCorpService {

    private EsignProperties esignProperties;

    private ESignAuthServiceImpl esignAuthService;

    private CommonService commonService;

    private ElecCorpMapper elecCorpMapper;

    private EsignOrgMemberMapper esignOrgMemberMapper;

    private EsignPsnInfoMapper esignPsnInfoMapper;

    private ElecCorpDeptMapper elecCorpDeptMapper;

    private EmployeeMapper employeeMapper;

    private HrmEContractTaskMapper hrmEContractTaskMapper;


    @Override
    public PageInfo<ElecCorpSelectVo> page(ElecCorpSelectBo param) {
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<ElecCorpSelectVo> list = elecCorpMapper.selectElecCorpPageList(param);
        return new PageInfo<>(list);
    }


    @Override
    public List<JSONObject> selectList(ElecCorpSelectBo param) {
        List<ElecCorpSelectVo> list = elecCorpMapper.selectElecCorpList(param);
        List<JSONObject> resultList = new ArrayList<>();
        list.forEach(elecCorp -> {
            JSONObject result = new JSONObject();
            result.put("id", elecCorp.getCorpId());
            result.put("value", elecCorp.getCorpName());
            resultList.add(result);
        });
        return resultList;
    }


    @Override
    public List<JSONObject> selectIdNameList() {
        List<JSONObject> jsonObjectList = elecCorpMapper.selectIdNameList();
        return jsonObjectList;
    }

    @Override
    public List<JSONObject> corpBySelect() {
        Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
        EmployeeDO employeeDO = employeeMapper.selectByUserId(loginUserId);
        if (ObjectUtils.isEmpty(employeeDO)) {
            return new ArrayList<>();
        }
        List<ElecCorpDept> elecCorpDepts = elecCorpDeptMapper.selectList(new LambdaQueryWrapper<ElecCorpDept>() {{
            eq(ElecCorpDept::getDeptId, employeeDO.getDeptId());
        }});
        if (ObjectUtils.isEmpty(elecCorpDepts)) {
            return new ArrayList<>();
        } else {
            Set<Integer> collect = elecCorpDepts.stream().map(ElecCorpDept::getCropId).collect(Collectors.toSet());
            List<ElecCorp> elecCorps = elecCorpMapper.selectList(new LambdaQueryWrapper<ElecCorp>() {{
                in(ElecCorp::getId, collect);
                eq(ElecCorp::getEsignAuthorizedStatus, 1);
                eq(ElecCorp::getEsignRealnameStatus, 1);
                eq(ElecCorp::getState, 1);
            }});
            List<JSONObject> resultList = new ArrayList<>();
            elecCorps.forEach(elecCorp -> {
                JSONObject result = new JSONObject();
                result.put("id", elecCorp.getId());
                result.put("value", elecCorp.getCorpName());
                resultList.add(result);
            });
            return resultList;

        }
    }


    @Override
    public ElecCorpPermissionVo permission(long corpId) {
        Long loginId = SecurityFrameworkUtils.getLoginUserId();
        // 基本信息
        EmployeeDO employee = commonService.checkEmployeeIdentify(loginId);
        ElecCorp elecCorp = commonService.checkCorpIdentify(corpId);
        // 成员角色
        List<EsignOrgMember> memberRoles = esignOrgMemberMapper.selectList(new LambdaQueryWrapper<EsignOrgMember>() {
            {
                eq(EsignOrgMember::getPsnId, employee.getEsignPsnId());
                eq(EsignOrgMember::getOrgId, elecCorp.getEsignOrgId());
            }
        });
        List<String> roles = memberRoles.stream().map(item -> item.getRole().trim()).collect(Collectors.toList());
        // 结果
        ElecCorpPermissionVo result = new ElecCorpPermissionVo();
        result.setGeneralPerm(roles.contains("1"));
        result.setSealManagePerm(roles.contains("2"));
        result.setMemberManagePerm(roles.contains("3"));
        result.setTemplateManagePerm(roles.contains("4"));
        result.setLegalRepPerm(roles.contains("98"));
        result.setAdministratorPerm(roles.contains("99"));
        return result;
    }


    @Override
    public ElecCorpDetailVo detail(long corpId) {
        ElecCorp elecCorp = commonService.checkCorpIdentify(corpId);
        // 基础查询
        ElecCorpDetailVo result = elecCorpMapper.selectElecCorpDetail(corpId);
        // 查询企业总管理员
        EsignOrgMember adminMember = esignOrgMemberMapper.selectOne(new LambdaQueryWrapper<EsignOrgMember>() {
            {
                eq(EsignOrgMember::getOrgId, elecCorp.getEsignOrgId());
                eq(EsignOrgMember::getRole, "99");
                last("limit 1");
            }
        });
        if (adminMember != null) {
            EsignPsnInfo adminInfo = esignPsnInfoMapper.selectById(adminMember.getPsnId());
            result.setAdministratorName(adminInfo.getPsnName());
        }
        // 脱敏身份证号
        result.setLegalRepIdCardNum(desensitizeIdNumber(result.getLegalRepIdCardNum()));
        // 格式化授权信息
        if (result.getEsignAuthorizedStatus() == 1 && StrUtil.isNotBlank(result.getOrgAuthorizedInfoKey())) {
            List<String> authorizedInfo = Arrays.stream(result.getOrgAuthorizedInfoKey().split(",")).map(String::trim)
                    .filter(code -> !code.isEmpty())
                    .map(code -> OrgAuthScope.ORG_AUTH_SCOPE_NAME.getOrDefault(code.toLowerCase(), "--"))
                    .collect(Collectors.toList());
            result.setOrgAuthorizedInfo(authorizedInfo);
        }

        return result;
    }


    @Override
    public void create(ElecCorpCreateBo param) {

        // 校验企业主体名称是否存在
        boolean nameExists = elecCorpMapper.exists(new LambdaQueryWrapper<ElecCorp>() {
            {
                eq(ElecCorp::getCorpName, param.getCorpName());
            }
        });
        if (nameExists) {
            throw new ResultException("企业信息已存在");
        }

        // 校验统一社会信用代码是否存在
//        boolean codeExists = elecCorpMapper.exists(new LambdaQueryWrapper<ElecCorp>() {
//            {
//                eq(ElecCorp::getCorpCreditCode, param.getCorpCreditCode());
//            }
//        });
//        if (codeExists) {
//            throw new ResultException("企业信息已存在");
//        }


        ElecCorp insert = new ElecCorp();
        copyBeanProps(param, insert);
        insert.setCreateBy(SecurityFrameworkUtils.getLoginUser().getId());
        insert.setCreateTime(DateUtil.currentDateFormat());
        EmployeeDO employeeDO = employeeMapper.selectByUserId(insert.getCreateBy());
        if (employeeDO == null) {
            insert.setCreateByName("管理员");
        } else {
            insert.setCreateByName(employeeDO.getName());
        }
        elecCorpMapper.insert(insert);
        if (!ObjectUtils.isEmpty(param.getDeptIdList())) {
            param.getDeptIdList().forEach(deptId -> {
                ElecCorpDept elecCorpDept = new ElecCorpDept();
                elecCorpDept.setDeptId(deptId.intValue());
                elecCorpDept.setCropId(insert.getId().intValue());

                elecCorpDeptMapper.insert(elecCorpDept);
            });
        }
    }

    @Override
    public ElecCorpUpdateBo update(long corpId) {
        ElecCorp elecCorp = elecCorpMapper.selectById(corpId);
        if (elecCorp == null) {
            throw new ResultException("企业不存在");
        }
//        if (elecCorp.getEsignRealnameStatus() == 1) {
//            throw new ResultException("企业已认证");
//        }

        ElecCorpUpdateBo result = new ElecCorpUpdateBo();
        List<ElecCorpDept> elecCorpDepts = elecCorpDeptMapper.selectList(new LambdaQueryWrapper<ElecCorpDept>() {{
            eq(ElecCorpDept::getCropId, corpId);
        }});
        if (!ObjectUtils.isEmpty(elecCorpDepts)) {
            List<Integer> collect = elecCorpDepts.stream().map(ElecCorpDept::getDeptId).collect(Collectors.toList());
            result.setDeptIdList(collect);
        }
        copyBeanProps(elecCorp, result);

        return result;
    }


    @Override
    public void update(ElecCorpUpdateBo param) {

        ElecCorp elecCorp = elecCorpMapper.selectById(param.getId());
        if (elecCorp == null) {
            throw new ResultException("企业不存在");
        }

//        if (elecCorp.getEsignRealnameStatus() == 1) {
//            throw new ResultException("企业已认证");
//        }

        // 校验企业主体名称是否存在
        boolean nameExists = elecCorpMapper.exists(new LambdaQueryWrapper<ElecCorp>() {
            {
                eq(ElecCorp::getCorpName, param.getCorpName());
                ne(ElecCorp::getId, param.getId());
            }
        });
        if (nameExists) {
            throw new ResultException("企业信息已存在");
        }
        // 校验统一社会信用代码是否存在
//        boolean codeExists = elecCorpMapper.exists(new LambdaQueryWrapper<ElecCorp>() {
//            {
//                eq(ElecCorp::getCorpCreditCode, param.getCorpCreditCode());
//                ne(ElecCorp::getId, param.getId());
//            }
//        });
//        if (codeExists) {
//            throw new ResultException("企业信息已存在");
//        }

        elecCorpMapper.update(null, new LambdaUpdateWrapper<ElecCorp>() {
            {
                eq(ElecCorp::getId, param.getId());
                set(!ObjectUtils.isEmpty(param.getCorpName()), ElecCorp::getCorpName, param.getCorpName());
                set(!ObjectUtils.isEmpty(param.getCorpCreditCode()), ElecCorp::getCorpCreditCode, param.getCorpCreditCode());
                set(!ObjectUtils.isEmpty(param.getLegalRepName()), ElecCorp::getLegalRepName, param.getLegalRepName());
                set(!ObjectUtils.isEmpty(param.getState()), ElecCorp::getState, param.getState());
            }
        });
        elecCorpDeptMapper.delete(new LambdaQueryWrapper<ElecCorpDept>() {
            {
                eq(ElecCorpDept::getCropId, elecCorp.getId());
            }
        });


        if (!ObjectUtils.isEmpty(param.getDeptIdList())) {
            param.getDeptIdList().forEach(deptId -> {
                ElecCorpDept elecCorpDept = new ElecCorpDept();
                elecCorpDept.setDeptId(deptId.intValue());
                elecCorpDept.setCropId(elecCorp.getId().intValue());
                elecCorpDeptMapper.insert(elecCorpDept);
            });
        }
    }

    @Override
    public void remove(long corpId) {
        ElecCorp elecCorp = elecCorpMapper.selectById(corpId);
        if (elecCorp == null) {
            throw new ResultException("企业不存在");
        }
        Long l = hrmEContractTaskMapper.selectCount(new LambdaQueryWrapper<HrmEContractTask>() {{
            eq(HrmEContractTask::getCorpId, corpId);
            notIn(HrmEContractTask::getTaskStatus, 8, 11);
        }});
        if (l > 0) {
            throw new ResultException("存在待签署合同不可删除");
        }
        elecCorpMapper.deleteById(corpId);
        elecCorpDeptMapper.delete(new LambdaQueryWrapper<ElecCorpDept>() {
            {
                eq(ElecCorpDept::getCropId, elecCorp.getId());
            }
        });
    }


    @Override
    public OrgIdentifyVo identify(OrgIdentifyBo param) {
        Long loginId = SecurityFrameworkUtils.getLoginUserId();
//        System.err.println(loginId);
        EmployeeDO employee = commonService.checkEmployeeIdentify(loginId);
//        System.err.println();
        ElecCorp elecCorp = elecCorpMapper.selectById(param.getCorpId());
        if (elecCorp == null) {
            throw new ResultException("企业不存在");
        }
        if (elecCorp.getEsignRealnameStatus() == 1 && elecCorp.getEsignAuthorizedStatus() == 1) {
            throw new ResultException("企业已完成认证/授权");
        }

        EsignPsnInfo esignPsnInfo = esignPsnInfoMapper.selectOne(new LambdaQueryWrapper<EsignPsnInfo>() {{
            eq(EsignPsnInfo::getPsnId, employee.getEsignPsnId());
            orderByDesc(EsignPsnInfo::getPsnAuthorizedStatus);
            last(" limit 1");
        }});
        if (ObjectUtils.isEmpty(esignPsnInfo)) {
            throw new ResultException("请先完成个人实名认证");
        }
        try {
            OrgAuthResp authResp = esignAuthService.getOrgAuthUrl(elecCorp.getCorpName(), elecCorp.getCorpCreditCode(),
                    elecCorp.getLegalRepName(), employee.getEsignPsnId(), param.getRedirectUrl(), false);
            // 更新实名授权流程ID
            elecCorpMapper.update(null, new LambdaUpdateWrapper<ElecCorp>() {
                {
                    eq(ElecCorp::getId, elecCorp.getId());
                    set(ElecCorp::getEsignAuthFlowId, authResp.getAuthFlowId());
                }
            });
            return OrgIdentifyVo.builder().authUrl(authResp.getAuthUrl()).build();
        } catch (EsignException e) {
            log.error("获取认证/授权地址失败，requestBody={}，msg = {}", param, e.getMessage());
            throw new ResultException("操作失败，请联系管理员");
        }
    }


    @Override
    public String selectAuthUrl(String orgId) {
        ElecCorp elecCorp = elecCorpMapper.selectOne(new LambdaQueryWrapper<ElecCorp>() {{
            eq(ElecCorp::getEsignOrgId, orgId);
        }});
        return elecCorp.getAuthorizeUrl();
    }
}
